package team.seekers.hula.course.resource.exam.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import team.seekers.hula.common.entity.result.ApiExceptionEnum;
import team.seekers.hula.common.utils.AssertUtils;
import team.seekers.hula.common.utils.BaseConvertUtils;
import team.seekers.hula.course.course.service.CourseService;
import team.seekers.hula.course.resource.exam.dao.ExamDao;
import team.seekers.hula.course.resource.exam.entity.dao.ExamDO;
import team.seekers.hula.course.resource.exam.entity.dto.ExamProblemDTO;
import team.seekers.hula.course.resource.exam.entity.dto.ExamQueryDTO;
import team.seekers.hula.course.resource.exam.entity.vo.ExamInfoVO;
import team.seekers.hula.course.resource.exam.entity.vo.ExamProblemListVO;
import team.seekers.hula.course.resource.exam.entity.vo.ExamProblemManageListVO;
import team.seekers.hula.course.resource.examSubmit.entity.dto.ExamRecordDTO;
import team.seekers.hula.course.resource.examSubmit.service.ExamRecordService;
import team.seekers.hula.course.resource.problem.entity.dto.ProblemDTO;
import team.seekers.hula.course.resource.problem.service.ProblemService;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Slf4j
@Service
public class ExamService {

    @Autowired
    private ExamDao examDao;

    @Autowired
    private ExamRecordService examRecordService;

    @Autowired
    private ProblemService problemService;

    @Autowired
    private CourseService courseService;

    public ExamInfoVO getInfoVO(String examId) {
        ExamDO examDO = examDao.getById(examId);
        ExamInfoVO examInfoVO = new ExamInfoVO();
        BeanUtils.copyProperties(examDO,examInfoVO);


        List<ExamProblemDTO> examProblems = BaseConvertUtils.bytesToObjectList(examDO.getProblems());
        ArrayList<String> problemIds = new ArrayList<>();
        for (ExamProblemDTO examProblemDTO : examProblems) {
            problemIds.add(examProblemDTO.getId());
        }
        Map<String, ProblemDTO> longProblemDTOMap = problemService.idsMapDTO(problemIds);

        ArrayList<ExamProblemManageListVO> examProblemManageListVOS = new ArrayList<>();
        for (ExamProblemDTO examProblem : examProblems) {
            ExamProblemManageListVO examProblemManageListVO = new ExamProblemManageListVO();
            BeanUtils.copyProperties(examProblem,examProblemManageListVO);
            examProblemManageListVO.setDescription(longProblemDTOMap.get(examProblem.getId()).getDescription());
            examProblemManageListVOS.add(examProblemManageListVO);
        }

        examInfoVO.setProblems(examProblemManageListVOS);
        return examInfoVO;
    }

    /**
     * 获取测试集合
     */
    public List<ExamQueryDTO> queryByIds(List<Long> examIds) {
        List<ExamDO> exams = examDao.lambdaQuery().select(
                ExamDO::getId,
                ExamDO::getTitle,
                ExamDO::getDescription,
                ExamDO::getProblems
        ).in(ExamDO::getId, examIds).list();
        AssertUtils.isTrue(exams.size() == examIds.size(), ApiExceptionEnum.CONTEST_PART_NOT_FOUND);

        ArrayList<ExamQueryDTO> examQueryDTOS = new ArrayList<>();
        for (ExamDO exam : exams) {
            ExamQueryDTO examDTO = new ExamQueryDTO();
            BeanUtils.copyProperties(exam,examDTO);
            examDTO.setProblems(BaseConvertUtils.bytesToObjectList(exam.getProblems()));
            examQueryDTOS.add(examDTO);
        }
        return examQueryDTOS;
    }

//    /**
//     * 获取课程下所有章节测试集合
//     * @return 返回每个章的测试集合，第一层List的下标是章的计数
//     */
//    public List<List<ExamQueryDTO>> listChapterExamByCourseId(String courseId, String userId) {
//        List<List<ExamQueryDTO>> listArrayList = new ArrayList<>();
//        List<String> chapterIds = courseService.idToChapterIds(courseId);
//
//        for (String chapterId : chapterIds) {
//            ArrayList<ExamQueryDTO> examQueryDTOS = new ArrayList<>();
//            List<ExamDO> examDOS = examDao.lambdaQuery().eq(ExamDO::getChapterId, chapterId).list();
//            for (ExamDO examDO : examDOS) {
//                ExamQueryDTO examQueryDTO = new ExamQueryDTO();
//                BeanUtils.copyProperties(examDO,examQueryDTO);
//                examQueryDTO.setProblems(BaseConvertUtils.bytesToObjectList(examDO.getProblems()));
//
//                List<ExamRecordDTO> list1 = examRecordService.list(examQueryDTO.getId(),userId);
//                examQueryDTO.setRecords(list1);
//
//                Double score = 0.0;
//                for (ExamRecordDTO examRecordDTO : list1) {
//                    score = Math.max(score,examRecordDTO.getScore());
//                }
//                examQueryDTO.setScore(score);
//
//                examQueryDTOS.add(examQueryDTO);
//            }
//            listArrayList.add(examQueryDTOS);
//        }
//        return listArrayList;
//    }

    public List<ExamQueryDTO> listFinalExamByCourseId(String courseId, String userId) {
        ArrayList<ExamQueryDTO> examQueryDTOS = new ArrayList<>();
        List<ExamDO> examDOS = examDao.lambdaQuery()
                .eq(ExamDO::getCourseId, courseId)
                .list();
        for (ExamDO examDO : examDOS) {
            ExamQueryDTO examQueryDTO = new ExamQueryDTO();
            BeanUtils.copyProperties(examDO,examQueryDTO);
            examQueryDTO.setProblems(BaseConvertUtils.bytesToObjectList(examDO.getProblems()));

            List<ExamRecordDTO> list1 = examRecordService.list(examQueryDTO.getId(),userId);
            examQueryDTO.setRecords(list1);
            examQueryDTOS.add(examQueryDTO);
        }
        return examQueryDTOS;
    }





    public List<ExamProblemListVO> queryExamProblems(String examId) {
        ExamDO examDO = examDao.getById(examId);
        List<ExamProblemDTO> examProblemDTOS = BaseConvertUtils.bytesToObjectList(examDO.getProblems());


        ArrayList<String> problemIds = new ArrayList<>();
        for (ExamProblemDTO examProblemDTO : examProblemDTOS) {
            problemIds.add(examProblemDTO.getId());
        }
        Map<String,ProblemDTO> map = problemService.idsMapDTO(problemIds);

        ArrayList<ExamProblemListVO> examProblemListVOS = new ArrayList<>();
        for (ExamProblemDTO examProblemDTO : examProblemDTOS) {
            ExamProblemListVO examProblemListVO = new ExamProblemListVO();
            examProblemListVO.setCriteria(examProblemDTO.getCriteria());
            BeanUtils.copyProperties(map.get(examProblemDTO.getId()),examProblemListVO);
            examProblemListVOS.add(examProblemListVO);
        }
        return examProblemListVOS;
    }

//    /**
//     * 获取某一章的测试信息（简介）
//     */
//    public List<ExamQueryDTO> querySimpleCourseExamsByChapterId(String chapterId) {
//        List<ExamDO> exams = examDao.lambdaQuery().select(
//                ExamDO::getId,
//                ExamDO::getTitle
//        ).eq(ExamDO::getChapterId, chapterId).list();
//        ArrayList<ExamQueryDTO> examQueryDTOS = new ArrayList<>();
//        for (ExamDO exam : exams) {
//            ExamQueryDTO examQueryDTO = new ExamQueryDTO();
//            BeanUtils.copyProperties(exam,examQueryDTO);
//            examQueryDTOS.add(examQueryDTO);
//        }
//        return examQueryDTOS;
//    }

//    /**
//     * 获取某一章的测试信息（带进度的具体信息）
//     */
//    public List<ExamQueryDTO> queryDetailCourseExamsByChapterId(String chapterId) {
//        List<ExamDO> exams = examDao.lambdaQuery().select(
//                ExamDO::getId,
//                ExamDO::getTitle,
//                ExamDO::getDescription
//        ).eq(ExamDO::getChapterId, chapterId).list();
//        ArrayList<ExamQueryDTO> examQueryDTOS = new ArrayList<>();
//        for (ExamDO exam : exams) {
//            ExamQueryDTO examQueryDTO = new ExamQueryDTO();
//            BeanUtils.copyProperties(exam,examQueryDTO);
//            examQueryDTOS.add(examQueryDTO);
//        }
//        return examQueryDTOS;
//    }



    public Map<String, ExamProblemDTO> idToProblemDTOMap(String examId) {
        List<ExamProblemDTO> examProblemDTOS = BaseConvertUtils.bytesToObjectList(examDao.lambdaQuery().select(
                ExamDO::getId,
                ExamDO::getProblems
        ).eq(ExamDO::getId, examId).one().getProblems());

        HashMap<String, ExamProblemDTO> longExamProblemDTOHashMap = new HashMap<>();
        for (ExamProblemDTO examProblemDTO : examProblemDTOS) {
            longExamProblemDTOHashMap.put(examProblemDTO.getId(),examProblemDTO);
        }
        return longExamProblemDTOHashMap;
    }

    public ExamQueryDTO queryById(String examId) {
        ExamDO exam = examDao.lambdaQuery().select(
                ExamDO::getId,
                ExamDO::getTitle,
                ExamDO::getCourseId,
                ExamDO::getTotalScore,
                ExamDO::getLimitDuration,
                ExamDO::getDescription,
                ExamDO::getProblems
        ).eq(ExamDO::getId, examId).one();
        ExamQueryDTO examDTO = new ExamQueryDTO();
        BeanUtils.copyProperties(exam,examDTO);
        examDTO.setProblems(BaseConvertUtils.bytesToObjectList(exam.getProblems()));
        return examDTO;
    }


    public ExamInfoVO getBindInfoVOByExamId(String sectionId) {
        ExamDO examDO = examDao.lambdaQuery().select()
                .eq(ExamDO::getSectionId,sectionId)
                .one();
        ExamInfoVO examInfoVO = new ExamInfoVO();
        BeanUtils.copyProperties(examDO,examInfoVO);


        List<ExamProblemDTO> examProblems = BaseConvertUtils.bytesToObjectList(examDO.getProblems());
        ArrayList<String> problemIds = new ArrayList<>();
        for (ExamProblemDTO examProblemDTO : examProblems) {
            problemIds.add(examProblemDTO.getId());
        }
        Map<String, ProblemDTO> longProblemDTOMap = problemService.idsMapDTO(problemIds);

        ArrayList<ExamProblemManageListVO> examProblemManageListVOS = new ArrayList<>();
        for (ExamProblemDTO examProblem : examProblems) {
            ExamProblemManageListVO examProblemManageListVO = new ExamProblemManageListVO();
            BeanUtils.copyProperties(examProblem,examProblemManageListVO);
            examProblemManageListVO.setDescription(longProblemDTOMap.get(examProblem.getId()).getDescription());
            examProblemManageListVOS.add(examProblemManageListVO);
        }

        examInfoVO.setProblems(examProblemManageListVOS);
        return examInfoVO;
    }
}
